home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / elib-006.lha / elib-0.06 / library / string.el < prev   
Lisp/Scheme  |  1993-01-24  |  5KB  |  146 lines

  1. ;;;; $Id: string.el,v 0.8 1993/01/17 23:18:53 ceder Exp $
  2. ;;;; This file contains some miscellaneous string functions
  3. ;;;;
  4. ;;;; Copyright (C) 1991, 1992 Free Software Foundation
  5. ;;;;
  6. ;;;; This file is part of the GNU Emacs lisp library, Elib.
  7. ;;;;
  8. ;;;; GNU Elib is free software; you can redistribute it and/or modify
  9. ;;;; it under the terms of the GNU General Public License as published by
  10. ;;;; the Free Software Foundation; either version 1, or (at your option)
  11. ;;;; any later version.
  12. ;;;;
  13. ;;;; GNU Elib is distributed in the hope that it will be useful,
  14. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ;;;; GNU General Public License for more details.
  17. ;;;;
  18. ;;;; You should have received a copy of the GNU General Public License
  19. ;;;; along with GNU Emacs; see the file COPYING.  If not, write to
  20. ;;;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21. ;;;; 
  22. ;;;; Author: Sebastian Kremer
  23. ;;;;         sk@thp.Uni-Koeln.DE
  24. ;;;; 
  25.  
  26. ;;;
  27. ;;; This file is part of the elisp library Elib.
  28. ;;; It implements simple generic string functions for use in other 
  29. ;;; elisp code: replace regexps in strings, split strings on regexps.
  30. ;;; 
  31.  
  32.  
  33. (provide 'string)
  34.  
  35.  
  36. ;; This function is a near-equivalent of the elisp function replace-match
  37. ;; which work on strings instead of a buffer.  The FIXEDCASE parameter
  38. ;; of replace-match is not implemented.
  39.  
  40. (defun string-replace-match (regexp string newtext &optional literal global)
  41.   "Replace first match of REGEXP in STRING with NEWTEXT.
  42. If no match is found, nil is returned instead of the new string.
  43.  
  44. Optional arg LITERAL non-nil means to take NEWTEXT literally. If LITERAL is 
  45. nil, character `\\' is the start of one of the following sequences:
  46.   \\\\   will be replaced by a single \\.
  47.   \\&   will be replaced by the text which matched the regexp.
  48.   \\N   where N is a number and 1 <= N <= 9, will be replaced
  49.        by the Nth subexpression in REGEXP. Subexpressions are grouped
  50.        inside \\( \\).
  51.  
  52. Optional arg GLOBAL means to replace all matches instead of only the first."
  53.  
  54.   (let ((data (match-data)))
  55.     (unwind-protect
  56.  
  57.     (if global
  58.         (let ((result "") 
  59.           (start 0)
  60.           matchbeginning
  61.           matchend)
  62.           (while (string-match regexp string start)
  63.         (setq matchbeginning (match-beginning 0)
  64.               matchend (match-end 0)
  65.               result (concat result
  66.                      (substring string start matchbeginning)
  67.                      (if literal
  68.                      newtext
  69.                        (elib-string-expand-newtext)))
  70.               start matchend))
  71.  
  72.           (if matchbeginning    ; matched at least once
  73.           (concat result (substring string start))
  74.         nil))
  75.  
  76.       ;; not GLOBAL
  77.       (if (not (string-match regexp string 0))
  78.           nil
  79.         (concat (substring string 0 (match-beginning 0))
  80.             (if literal newtext (elib-string-expand-newtext))
  81.             (substring string (match-end 0)))))
  82.       (store-match-data data))))
  83.  
  84.  
  85. (defun elib-string-expand-newtext ()
  86.   ;; Expand \& and \1..\9 (referring to STRING) in NEWTEXT.
  87.   ;; Uses match data and fluid vars `newtext', `string'.
  88.   ;; Note that in Emacs 18 match data are clipped to current buffer
  89.   ;; size...so the buffer should better not be smaller than STRING.
  90.   (let ((pos 0)
  91.     (len (length newtext))
  92.     (expanded-newtext ""))
  93.     (while (< pos len)
  94.       (setq expanded-newtext
  95.         (concat expanded-newtext
  96.             (let ((c (aref newtext pos)))
  97.               (if (= ?\\ c)
  98.               (cond ((= ?\& (setq c (aref newtext
  99.                               (setq pos (1+ pos)))))
  100.                  (substring string
  101.                         (match-beginning 0)
  102.                         (match-end 0)))
  103.                 ((and (>= c ?1) 
  104.                       (<= c ?9))
  105.                  ;; return empty string if N'th
  106.                  ;; sub-regexp did not match:
  107.                  (let ((n (- c ?0)))
  108.                    (if (match-beginning n)
  109.                        (substring string
  110.                           (match-beginning n)
  111.                           (match-end n))
  112.                      "")))
  113.                 (t (char-to-string c)))
  114.             (char-to-string c)))))
  115.       (setq pos (1+ pos)))
  116.     expanded-newtext))
  117.  
  118.  
  119. (defun string-split (pattern string &optional limit)
  120.   "Splitting on regexp PATTERN, turn string STRING into a list of substrings.
  121. Optional third arg LIMIT (>= 1) is a limit to the length of the
  122. resulting list."
  123.  
  124.   (let ((data (match-data)))
  125.     (unwind-protect
  126.     (let* ((start (string-match pattern string))
  127.            (result (list (substring string 0 start)))
  128.            (count 1)
  129.            (end (if start (match-end 0))))
  130.       (if end            ; else nothing left
  131.           (while (and (or (not (integerp limit))
  132.                   (< count limit))
  133.               (string-match pattern string end))
  134.         (setq start (match-beginning 0)
  135.               count (1+ count)
  136.               result (cons (substring string end start) result)
  137.               end (match-end 0)
  138.               start end)))
  139.       (if (and (or (not (integerp limit))
  140.                (< count limit))
  141.            end)            ; else nothing left
  142.           (setq result
  143.             (cons (substring string end) result)))
  144.       (nreverse result))
  145.       (store-match-data data))))
  146.